package com.zhang.zxx.pattern.strategy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * StrategyHandler:策略处理类[可以理解为策略工厂类],Map<Integer, StrategyService>也可以使用private static final 修饰
 *
 * @author zhangxiaoxiang
 * @date 18/7/2021
 */
@Component
@Slf4j
public class StrategyHandler implements BeanPostProcessor {

    Map<Integer, StrategyService> handlers = new ConcurrentHashMap<>();

    public Object handler(Integer key) {
        // 如果没有找到正常业务策略实现类处理方式1:写一个默认策略,比如HANDLERS.get(0)表示找到默认策略[兜底保留策略]
        Object result = Optional.ofNullable(handlers.get(key)).orElse(handlers.get(LoginEnum.DEFAULT.getKey())).handler(key);
        // 如果没有找到正常业务策略实现类处理方式2:直接抛业务异常,调用方处理,两种方式根据业务情况自行选择就行
        // Object result = Optional.ofNullable(HANDLERS.get(type)).orElseThrow(() -> new RuntimeException("未找到定义的策略实现类[抛出的业务异常]")).handler(o);
        log.info("从容器获取到:key={},对应的StrategyService处理结果:{}", key, result);
        return result;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof StrategyService) {
            StrategyService service = (StrategyService) bean;
            handlers.put(service.matchKey(), service);
        }
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }
}